package util

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"github.com/shopspring/decimal"
)

// 将一个绝对路径的文件读入到字节数组中
func ReadAll(absolutePath string) ([]byte, error) {
	f, err := os.Open(absolutePath)
	if err != nil {
		return nil, err
	}

	defer f.Close()

	return io.ReadAll(f)
}

// 相对工程的路径读取文件到字节数组中
func Read(realtiveFile string) (data []byte, err error) {
	d, err := os.Getwd()
	if err != nil {
		return
	}

	realPath, err := filepath.EvalSymlinks(d)
	if err != nil {
		return
	}

	data, err = ReadAll(realPath + "/" + realtiveFile)
	return
}

// 相对工程的路径读取json文件, i 接收数据的对象指针
func ReadJson(realtiveFile string, i interface{}) (err error) {
	d, err := Read(realtiveFile)
	if err != nil {
		return
	}

	return json.Unmarshal(d, i)
}

// 将字符串写到文件中，filePath为绝对路径
func WriteString(filePath string, data string) error {
	return os.WriteFile(filePath, []byte(data), 0644)
}

// 字符串写入文件，file路径为相对当前工程的路径。
func WriteStringRelative(file string, data string) error {
	d, err := os.Getwd()
	if err != nil {
		return err
	}

	realPath, err := filepath.EvalSymlinks(d)
	if err != nil {
		return err
	}

	return WriteString(realPath+"/"+file, data)
}

// 将对象序列化为Json文件，file路径为相对当前工程的路径。
func WriteJsonRelative(file string, obj interface{}) error {
	d, err := os.Getwd()
	if err != nil {
		return err
	}

	realPath, err := filepath.EvalSymlinks(d)
	if err != nil {
		return err
	}

	return WriteString(realPath+"/"+file, ObjectToJSONString(obj))
}

func FormatSize(size int) (s string) {
	unit := 1024
	dunit := decimal.NewFromInt(int64(unit))
	if size < unit {
		return fmt.Sprintf("%d B", size)
	}

	if size < int(dunit.Pow(decimal.NewFromFloat(2)).IntPart()) {
		d := decimal.NewFromInt(int64(size)).Div(dunit)
		return fmt.Sprintf("%s KB", d.StringFixed(2))
	}

	if size < int(dunit.Pow(decimal.NewFromFloat(3)).IntPart()) {
		d := decimal.NewFromInt(int64(size)).Div(dunit).Div(dunit)
		return fmt.Sprintf("%s MB", d.StringFixed(2))
	}

	return fmt.Sprintf("%d B", size)
}
